// src/client/client.cpp
#include "client.h"
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include "../common/message.h"

ChatClient::ChatClient(const std::string& server_ip, int server_port)
    : server_ip(server_ip), server_port(server_port), socket_fd(-1), running(false) {}

ChatClient::~ChatClient() {
    stop();
    if (socket_fd != -1) {
        close(socket_fd);
    }
}

bool ChatClient::connect_to_server() {
    // 创建socket
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd == -1) {
        std::cerr << "Failed to create socket" << std::endl;
        return false;
    }
    
    // 设置服务器地址
    sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    
    // 将IP地址从文本转换为二进制形式
    if (inet_pton(AF_INET, server_ip.c_str(), &server_addr.sin_addr) <= 0) {
        std::cerr << "Invalid address/ Address not supported" << std::endl;
        close(socket_fd);
        socket_fd = -1;
        return false;
    }
    
    // 连接服务器
    if (connect(socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        std::cerr << "Connection failed" << std::endl;
        close(socket_fd);
        socket_fd = -1;
        return false;
    }
    
    std::cout << "Connected to server " << server_ip << ":" << server_port << std::endl;
    return true;
}

void ChatClient::disconnect() {
    if (socket_fd != -1) {
        close(socket_fd);
        socket_fd = -1;
    }
}

void ChatClient::start() {
    if (!connect_to_server()) {
        return;
    }
    
    std::cout << "Enter your username: ";
    std::getline(std::cin, username);
    
    // 发送用户名到服务器
    send_message(username);
    
    running = true;
    
    // 创建接收和发送线程
    pthread_create(&receive_thread, nullptr, receive_thread_func, this);
    pthread_create(&send_thread, nullptr, send_thread_func, this);
    
    // 主线程处理消息显示
    process_messages();
}

void ChatClient::stop() {
    if (running) {
        running = false;
        
        // 等待线程结束
        pthread_join(receive_thread, nullptr);
        pthread_join(send_thread, nullptr);
        
        disconnect();
        std::cout << "Disconnected from server" << std::endl;
    }
}

void ChatClient::send_message(const std::string& message) {
    if (socket_fd == -1 || !running) {
        return;
    }
    
    ssize_t bytes_sent = write(socket_fd, message.c_str(), message.length());
    if (bytes_sent == -1) {
        std::cerr << "Failed to send message" << std::endl;
        stop();
    }
}

void ChatClient::receive_messages() {
    char buffer[1024];
    
    while (running) {
        memset(buffer, 0, sizeof(buffer));
        ssize_t bytes_received = read(socket_fd, buffer, sizeof(buffer));
        
        if (bytes_received <= 0) {
            std::cout << "Server disconnected" << std::endl;
            running = false;
            break;
        }
        
        // 创建文本消息并加入队列
        TextMessage* message = new TextMessage("Server", std::string(buffer));
        messageQueue.enqueue(message);
    }
}

void ChatClient::process_messages() {
    while (running) {
        if (!messageQueue.empty()) {
            Message* message = messageQueue.dequeue();
            std::cout << message->format() << std::endl;
            delete message; // 释放消息内存
        }
        
        // 短暂休眠避免CPU占用过高
        usleep(100000); // 100毫秒
    }
}

void* ChatClient::receive_thread_func(void* arg) {
    ChatClient* client = static_cast<ChatClient*>(arg);
    client->receive_messages();
    return nullptr;
}

void* ChatClient::send_thread_func(void* arg) {
    ChatClient* client = static_cast<ChatClient*>(arg);
    
    std::cout << "Type messages and press Enter to send. Type '/exit' to quit." << std::endl;
    
    std::string message;
    while (client->running) {
        std::getline(std::cin, message);
        
        if (message == "/exit") {
            client->stop();
            break;
        }
        
        client->send_message(message);
    }
    
    return nullptr;
}

int main() {
    ChatClient client("127.0.0.1", 8080);
    client.start();
    
    return 0;
}    